package Clients;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import java.text.NumberFormat;
import java.util.Locale;

import Catalogue.*;
import Middle.*;

/**
 * Implements the GUI for the Cashier client.
 * @author  Michael Alexander Smith
 * @version 2.1
 */

class CashierGUI
{
  private enum State { process, checked }

  private static final String CHECK  = "Check";
  private static final String BUY    = "Buy";
  private static final String CANCEL = "Cancel";
  private static final String BOUGHT = "Bought";
 

  private static final int H = 300;       // Height of window pixels
  private static final int W = 400;       // Width  of window pixels

  private JLabel      action  = new JLabel();
  private JTextField  input   = new JTextField();
  private JTextArea   output  = new JTextArea();
  private JScrollPane scrollPane	= new JScrollPane();
  private JButton     checkBtn = new JButton( CHECK );
  private JButton     buyBtn   = new JButton( BUY );
  private JButton     cancelBtn= new JButton( CANCEL );
  private JButton     boughtBtn= new JButton( BOUGHT );

  private State       state   = State.process;   // Current state
  private Product     product = null;            // Current product
  private SoldBasket  bought  = null;            // Bought items

  private Transaction     transaction        = new Transaction();
  private StockReadWriter stock     = null;
  private OrderProcessing order     = null;

  private NumberFormat money  =
          NumberFormat.getCurrencyInstance( Locale.UK );
  MiddleFactory mf;
  
  public CashierGUI(  RootPaneContainer rpc, MiddleFactory mf  )
  {
	  this.mf = mf;
    try                                           // 
    {      
      stock = mf.makeStockReadWriter();        // DataBase access
      order = mf.makeOrderProcessing();        // Process order
    } catch ( Exception e )
    {
      System.out.println("Exception: " + e.getMessage() );
    }
    Container container         = rpc.getContentPane();    // Content Pane
    Container rootWindow = (Container) rpc;         // Root Window
    container.setLayout(null);                             // No layout manager
    rootWindow.setSize( W, H );                     // Size of Window
    container.setBackground(Color.BLACK);

    Font f = new Font("Monospaced",Font.PLAIN,12);  // Font f is

    checkBtn.setBounds( 16, 25+60*0, 80, 40 );    // Check Button
    checkBtn.addActionListener( transaction );          // Listener
    checkBtn.setIcon(new ImageIcon("src/images/ButtonTex/buttonTex.png")); 	//Changes the background image
    checkBtn.setVerticalTextPosition(JButton.CENTER); 						// Sets the text to the middle
    checkBtn.setHorizontalTextPosition(JButton.CENTER); 						//to avoid it bumping the image around
    checkBtn.setBackground(Color.BLACK); 			//Sets the background to black
    checkBtn.setBorder(null); 					//Removes the border around the button
    checkBtn.setForeground(Color.WHITE); 			//Sets the font color to white
    checkBtn.setContentAreaFilled(false); 		//Does not allow the background to change when clicked
    container.add( checkBtn );                           //  Add to canvas

    buyBtn.setBounds( 16, 25+60*1, 80, 40 );      // Buy button 
    buyBtn.addActionListener( transaction );            //  Listener
    buyBtn.setIcon(new ImageIcon("src/images/ButtonTex/buttonTex.png")); 	//Changes the background image
    buyBtn.setVerticalTextPosition(JButton.CENTER); 						// Sets the text to the middle
    buyBtn.setHorizontalTextPosition(JButton.CENTER); 						//to avoid it bumping the image around
    buyBtn.setBackground(Color.BLACK); 			//Sets the background to black
    buyBtn.setBorder(null); 					//Removes the border around the button
    buyBtn.setForeground(Color.WHITE); 			//Sets the font color to white
    buyBtn.setContentAreaFilled(false); 		//Does not allow the background to change when clicked
    container.add( buyBtn );                             //  Add to canvas

    cancelBtn.setBounds( 16, 25+60*2, 80, 40 );   // Cancel Button
    cancelBtn.addActionListener( transaction );         //  Listener
    cancelBtn.setIcon(new ImageIcon("src/images/ButtonTex/buttonTex.png")); 	//Changes the background image
    cancelBtn.setVerticalTextPosition(JButton.CENTER); 						// Sets the text to the middle
    cancelBtn.setHorizontalTextPosition(JButton.CENTER); 						//to avoid it bumping the image around
    cancelBtn.setBackground(Color.BLACK); 			//Sets the background to black
    cancelBtn.setBorder(null); 					//Removes the border around the button
    cancelBtn.setForeground(Color.WHITE); 			//Sets the font color to white
    cancelBtn.setContentAreaFilled(false); 		//Does not allow the background to change when clicked
    container.add( cancelBtn );                          //  Add to canvas

    boughtBtn.setBounds( 16, 25+60*3, 80, 40 );   // Clear Button
    boughtBtn.addActionListener( transaction );         //  Listener
    boughtBtn.setIcon(new ImageIcon("src/images/ButtonTex/buttonTex.png")); 	//Changes the background image
    boughtBtn.setVerticalTextPosition(JButton.CENTER); 						// Sets the text to the middle
    boughtBtn.setHorizontalTextPosition(JButton.CENTER); 						//to avoid it bumping the image around
    boughtBtn.setBackground(Color.BLACK); 			//Sets the background to black
    boughtBtn.setBorder(null); 					//Removes the border around the button
    boughtBtn.setForeground(Color.WHITE); 			//Sets the font color to white
    boughtBtn.setContentAreaFilled(false); 		//Does not allow the background to change when clicked
    container.add( boughtBtn );                          //  Add to canvas

    action.setBounds( 110, 235 , 270, 20 );       // Message area
	action.setText("Please input the product number.");
	action.setForeground(Color.WHITE);
    container.add( action );                            //  Add to canvas

    input.setBounds( 110, 25, 270, 40 );         // Input Area
    input.setText("");  // Blank
	input.setBackground(Color.BLACK);
	input.setForeground(Color.WHITE);
	input.setBorder(BorderFactory.createLineBorder(Color.green));
    container.add( input );                             //  Add to canvas

    scrollPane.setBounds( 110, 75, 270, 160 );          // Scrolling pane
    output.setText( "" );                        //  Blank
    output.setFont( f );                         //  Uses font
    output.setEditable(false);
	scrollPane.setBorder(null);
	output.setBackground(Color.BLACK);
	output.setForeground(Color.WHITE);
	output.setBorder(BorderFactory.createLineBorder(Color.green));
    container.add( scrollPane );                                //  Add to canvas
    scrollPane.getViewport().add( output );           //  In TextArea
    rootWindow.setVisible( true );                  // Make visible
  }


  class Transaction implements ActionListener       // Listener
  {
    public void actionPerformed( ActionEvent ae )   // Interaction
    {
      if ( stock == null )
      {
        action.setText("No connection");
        return;                                     // No connection
      }
      String actionIs = ae.getActionCommand();      // Button
      try
      {
        if ( bought == null )
        {                                           // 
          int on    = order.uniqueNumber();      // Unique order no.
          bought = new SoldBasket( on );         //  Bought list
        }
        
        if ( actionIs.equals( CHECK ) )             // Button CHECK
        {
          state  = State.process;                // State process
          String pn  = input.getText().trim();   // Product no.
          int    amount  = 1;                       //  & quantity
  
          if ( stock.exists( pn ) )              // Stock Exists?
          {                                         // T
            Product pr = stock.getDetails(pn);   //  Get details
            if ( pr.getQuantity() >= amount )       //  In stock?
            {                                       //  T
              action.setText(                    //   Display 
                pr.getDescription() + " : " +       //    description
                money.format(pr.getPrice()) +    //    price
                " (" + pr.getQuantity() + ")"       //    quantity
              );                                    //   of product
              product = pr;                      //   Remember prod.
              product.setQuantity( amount );     //    & quantity
              state = State.checked;             //   OK await BUY 
            } else {                                //  F
              action.setText(                    //   Not in Stock
                pr.getDescription() +" not in stock"
              );
            }
          } else {                                  // F Stock exists
            action.setText(                      //  Unknown
              "Unknown product number " + pn        //  product no.
            );
          }
        }
  
        if ( actionIs.equals( BUY ) )               // Button BUY
        {
  
          if ( state != State.checked )          // Not checked
          {                                         //  with customer
            action.setText("Check if OK with customer first");
            return;
          }
          
          boolean stockBought =                      // Buy
            stock.buyStock(                       //  however
              product.getProductNo(),             //  may fail              
              product.getQuantity() );            //
          if ( stockBought )                         // Stock bought
          {                                          // T
            bought.add( product );             //  Add to bought
            output.setText( "" );                 //  clear
            output.append( bought.getDetails());//  Display
            action.setText("Purchased " +         //    details
                       product.getDescription()); //
          input.setText( "" );
          } else {                                   // F
            action.setText("!!! NOT IN STOCK !!!");   //  Now no stock
          }
          state = State.process;                  // All Done
        }
  
  
        if ( actionIs.equals( CANCEL ) )            // Button CANCEL
        {
          if ( bought.number() >= 1 )             // item to cancel
          {                                          // T
            Product pr =  bought.remove();        //  Remove from list
            stock.addStock( pr.getProductNo(),    //  Re-stock
                               pr.getQuantity()  );  //   as not sold
			action.setText("Please input the product number and amount.");
			input.setText("");
            output.setText(bought.getDetails());//  display sales
          } else {                                   // F
            output.setText( "" );                 //  Clear
          }
          state = State.process;
        }
  
        if ( actionIs.equals( BOUGHT ) )             // Button Bought
        { 
        	try{
    			System.err.println("order "+mf.makeOrderProcessing().getOrderState());
    		}catch(OrderException e){
    			System.err.println(e);
    		}
          if ( bought.number() >= 1 )             // items > 1
          {                                          // T
            order.newOrder( bought );          //  Process order
            bought = null;                        //  reset
          }                                          //
          output.setText( "" );                   // Clear
          input.setText( "" );                    //
          action.setText( "Next customer" );      // New Customer
          state = State.process;                  // All Done
        }
  
        input.requestFocus();                     // theInput has Focus

      }
      catch ( StockException e )                     // Error
      {                                              //  Of course
        output.append( "Fail Stock access:" +     //   Should not
                            e.getMessage() + "\n" ); //  happen
      }
      catch ( OrderException e )                     // Error
      {                                              //  Of course
        output.append( "Fail Order process:" +    //   Should not
                            e.getMessage() + "\n" ); //  happen
      }
    }
  }

}
